home *** CD-ROM | disk | FTP | other *** search
/ Scene 96 / Scene 96 International Edition (Zyklop Software) (Disc 2) (1997).iso / graphics / artpacks / acid0896 / vga.pas < prev    next >
Pascal/Delphi Source File  |  1996-08-01  |  16KB  |  301 lines

  1. {$A+,B-,D-,E-,F-,G-,I-,L-,N-,O-,P-,Q-,R-,S-,T-,V-,X+,Y+}
  2. UNIT VGA;
  3. {=============================================================================
  4.  
  5.   Unit VGA
  6.  
  7.   Provides VGA specific functions.
  8.      - VGA detection
  9.      - Setting palette
  10.      - Setting fonts & loading
  11.      ...
  12.  
  13. =============================================================================}
  14.  
  15. {▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀}
  16.                                 INTERFACE
  17. {▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄}
  18.  
  19. CONST  VGA_CRTC         = $03D4;       { Port address CRTC                   }
  20.        VGA_STATUS       = $03DA;       { Port address for Status register    }
  21.        VGA_AC           = $03C0;       { Port address Attribute controller   }
  22.        VGA_AC_READ      = $03C1;       { Read address Attribute controller   }
  23.        VGA_SR           = $03C4;       { Port address Sequencer register     }
  24.        VGA_GC           = $03CE;       { Port address Graphics controller    }
  25.        VGA_PEL_WRITE    = $03C8;       { Port address PEL Address Write      }
  26.        VGA_PEL_READ     = $03C7;       { Port address PEL Address Read       }
  27.        VGA_PEL_DATA     = $03C9;       { Port address PEL Data register      }
  28.  
  29. FUNCTION  VGA_IsPresent     : BOOLEAN;
  30. PROCEDURE VGA_Mode          (Mode : Byte);
  31. PROCEDURE VGA_SetPalette    (StartColor, NumColors:Byte; VAR Palette);
  32. PROCEDURE VGA_SetFlatTextPal;
  33. PROCEDURE VGA_SetBlink      (BlinkMode : BOOLEAN);
  34. PROCEDURE VGA_SetActiveFont (Font0, Font1 : Byte);
  35. PROCEDURE VGA_SetFontSize   (FontSize:Byte);
  36. PROCEDURE VGA_SetFont       (StartChar,NumChars, FontSize, VideoOffset : Word; VAR Font);
  37. PROCEDURE VGA_Set8PixelFont;
  38.  
  39. {▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀}
  40.                               IMPLEMENTATION
  41. {▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄}
  42.  
  43. { RETURN TRUE if VGA card is present }
  44. FUNCTION  VGA_IsPresent : BOOLEAN; ASSEMBLER;
  45. ASM
  46.               MOV    AX,01A00h         { ┬> Display Combination Code         }
  47.               INT    10h               { ┘                                   }
  48.               CMP    AL,01Ah           { Is AL=01Ah then it's a VGA          }
  49.               MOV    AL,TRUE           { Assume it'll be true                }
  50.               JE     @Return           { We were right, quit now             }
  51.               MOV    AL,FALSE          { We were wrong, return false         }
  52. @Return:
  53. END;
  54.  
  55.  
  56. PROCEDURE VGA_Mode       (Mode : Byte); ASSEMBLER;
  57. ASM
  58.               MOV    AH,0
  59.               MOV    AL,Mode
  60.               INT    10h
  61. END;
  62.  
  63.  
  64. PROCEDURE VGA_SetPalette (StartColor, NumColors:Byte; VAR Palette); ASSEMBLER;
  65. ASM
  66.               PUSH   DS                { Save DS                          }
  67.  
  68.               MOV    DX,VGA_PEL_WRITE  { DX = Palette address register    }
  69.               MOV    AL,[StartColor]   { AL = First Color to set          }
  70.               OUT    DX,AL             { Activate StartColor              }
  71.               MOV    AH,[NumColors]    { Get number of colors to modify   }
  72.               CMP    AH,0              { Is it Zero ?                     }
  73.               JE     @SetDone          { Yes, we don't need to do anything}
  74.               LDS    SI,Palette        { DS:SI points to palette data     }
  75.               CLD                      { Increment SI on LODSB            }
  76.               MOV    DX,VGA_PEL_DATA   { DX = Pallette data register      }
  77. @SetColor:    LODSB                    { Load RED                         }
  78.               OUT    DX,AL             { Set RED                          }
  79.               LODSB                    { Load GREEN                       }
  80.               OUT    DX,AL             { Set Green                        }
  81.               LODSB                    { LOAD BLUE                        }
  82.               OUT    DX,AL             { Set BLUE                         }
  83.               DEC    AH                { One color done                   }
  84.               JNZ    @SetColor         { Need to do more ?                }
  85. @SetDone:
  86.               POP    DS                { Restore DS                       }
  87. END;
  88.  
  89.  
  90. PROCEDURE VGA_SetFlatTextPal; ASSEMBLER;
  91. ASM
  92.               MOV    DX,VGA_STATUS     { CRTC Status register             }
  93.               IN     AL,DX             { Read CRTC Status. (This'll reset }
  94.                                        { Attribute controller flip-flop)  }
  95.             { Set EGA palette to color 0-15                               }
  96.               MOV    DX,VGA_AC         { Attribute controller             }
  97.               MOV    AL,0              { Color 0. (and Clears PAS field)  }
  98. @NxtPalEGA:   OUT    DX,AL             { Set paletteregister to change    }
  99.               OUT    DX,AL             { Set value for palette register   }
  100.               INC    AL                { Next color                       }
  101.               CMP    AL,0Fh            { All colors done ?                }
  102.               JBE    @NxtPalEGA        { Nope.                            }
  103.               MOV    AL,20h
  104.               OUT    DX,AL             { Set PAS field (Video has access  }
  105.                                        { to palette)                      }
  106. END;
  107.  
  108.  
  109. PROCEDURE VGA_SetBlink      (BlinkMode : BOOLEAN); ASSEMBLER;
  110. ASM
  111.               MOV    DX,VGA_STATUS     { CRTC Status register             }
  112.               IN     AL,DX             { Read CRTC Status. (This'll reset }
  113.                                        { Attribute controller flip-flop)  }
  114.             { Set blink bit }
  115.               MOV    DX,VGA_AC         { Attribute controller (Write port)}
  116.               MOV    AL,10h+20h        { Register 10h (Mode control)      }
  117.                                        { leave PAS field enabled.         }
  118.               OUT    DX,AL             { Activate register 10h            }
  119.               MOV    DX,VGA_AC_READ    { DX=003C1h (Attribute READ port)  }
  120.               IN     AL,DX             { Read Mode control register       }
  121.               MOV    DX,VGA_AC         { DX=003C0h (Attribute Write port) }
  122.               CMP    [BlinkMode],TRUE  { BlinkMode = TRUE ?               }
  123.               JE     @SetBlinkBit      {  Yes jump to SetBlinkBit         }
  124. @BlinkOff:    AND    AL,NOT 008h       { Clear the Blink bit              }
  125.               JMP    @SetBlinkBit      { And go tell the VGA card         }
  126. @BlinkOn:     OR     AL,008h           { Clear the Blink bit              }
  127. @SetBlinkBit:
  128.               OUT    DX,AL             { Rewrite Mode control register    }
  129. END;
  130.  
  131.  
  132. PROCEDURE VGA_SetActiveFont (Font0, Font1 : Byte); ASSEMBLER;
  133. ASM
  134.               MOV    DX,VGA_SR         { Sequencer register               }
  135.               MOV    AL,03             { Character Map Select             }
  136.  
  137.               MOV    BL,[Font0]        { Prepare 'Font0' for Character    }
  138.               MOV    BH,BL             { Generator B                      }
  139.               AND    BL,003h
  140.               AND    BH,004h
  141.               SHL    BH,1
  142.               SHL    BH,1
  143.               OR     BL,BH
  144.  
  145.               MOV    CL,[Font1]        { Prepare 'Font1' for Character    }
  146.               MOV    CH,CL             { Generator A                      }
  147.               AND    CL,003h
  148.               AND    CH,004h
  149.               SHL    CH,1
  150.               OR     CL,CH
  151.               SHL    CX,1
  152.               SHL    CX,1
  153.  
  154.               MOV    AH,BL             { Combine bits for Char Gen A and B }
  155.               OR     AH,CL             { ┘                                 }
  156.               OUT    DX,AX             { And activate the requested Char   }
  157.                                        { maps                              }
  158. END;
  159.  
  160.  
  161. PROCEDURE VGA_SetFontSize (FontSize:Byte); ASSEMBLER;
  162. ASM
  163.               MOV    DX,VGA_CRTC       { CRTC address register             }
  164.               MOV    AL,9              { Index for Max Scanline Register   }
  165.               OUT    DX,AL             { set MSL as active register        }
  166.               INC    DX                { Set DX to CRTC Data register      }
  167.               IN     AL,DX             { read current MSL                  }
  168.               AND    AL,011100000b     { set MSL to 0, preserve others bits}
  169.               MOV    AH,[FontSize]     { get required size                 }
  170.               DEC    AH                { minus one.                        }
  171.               OR     AL,AH             { set size in MSL field             }
  172.               OUT    DX,AL             { Writeback modified value          }
  173. END;
  174.  
  175.  
  176. PROCEDURE VGA_SetFont(StartChar, NumChars, FontSize, VideoOffset : Word; VAR Font); ASSEMBLER;
  177. ASM
  178. { === Switch VGA into linear/planar more, ready for receiving font data === }
  179.               CLI                      { No interrupts allowed             }
  180.               MOV    DX,VGA_SR         { Sequencer register                }
  181.               MOV    AX,0100h          { ┬> Synchronous reset              }
  182.               OUT    DX,AX             { ┘                                 }
  183.               MOV    AX,0402h          { ┬> Select Plane 2 for WRITE       }
  184.               OUT    DX,AX             { ┘                                 }
  185.               MOV    AX,0704h          { ┬> Sequential Addressing mode     }
  186.               OUT    DX,AX             { ┘                                 }
  187.               MOV    AX,0300h          { ┬> Release Synchronous reset      }
  188.               OUT    DX,AX             { ┘                                 }
  189.  
  190.               MOV    DX,VGA_GC         { Graphics controller register      }
  191.               MOV    AX,0204h          { ┬> Select Plane 2 for READ        }
  192.               OUT    DX,AX             { ┘                                 }
  193.               MOV    AX,0005h          { ┬> Disable odd addressing mode    }
  194.               OUT    DX,AX             { ┘                                 }
  195.               MOV    AX,0006h          { ┬> Memory range is A000:0000      }
  196.               OUT    DX,AX             { ┘                                 }
  197.               STI                      { Interrupts enabled                }
  198. { === LOAD the font ======================================================= }
  199.  
  200.               MOV    DI,[SegA000]      { ┐                                 }
  201.               MOV    ES,DI             { ├> ES:DI -> Video Address where   }
  202.               MOV    DI,[StartChar]    { │           to load font          }
  203.               SHL    DI,1              { │                                 }
  204.               SHL    DI,1              { │  DS=VideoOffset + Offset for    }
  205.               SHL    DI,1              { │     starting at <StartChar>     }
  206.               SHL    DI,1              { │                                 }
  207.               SHL    DI,1              { │                                 }
  208.               ADD    DI,[VideoOffset]  { ┘                                 }
  209.  
  210.               PUSH   DS                { Save DS                           }
  211.               LDS    SI,[Font]         { DS:SI -> Font                     }
  212.  
  213.               MOV    BX,[NumChars]     { Number of characters to load      }
  214.               CMP    BX,0
  215.               JE     @DoneLoad         { No characters to load, we're done }
  216.  
  217.               MOV    AX,[FontSize]
  218.               CLD                      { Increment pointers on MOVSB       }
  219.               MOV    DX,32             { ┬> DX= 32-FontSize (Size of gap in}
  220.               SUB    DX,AX             { │  between two videomemory        }
  221.                                        { ┘  characters                     }
  222.  
  223. @NextChar:    MOV    CX,AX             { Copy FontSize in CX               }
  224.               REP    MOVSB             { Copy current character            }
  225.               ADD    DI,DX             { Skip gap in videomemory           }
  226.               DEC    BX                { One character done                }
  227.               JNZ    @NextChar         { Still more to do ?                }
  228.  
  229. @DoneLoad:    POP    DS
  230.  
  231. { === Switch VGA back into normal textmode operation ====================== }
  232.               CLI                      { No interrupts allowed.            }
  233.               MOV    DX,VGA_SR         { Sequence controller register      }
  234.               MOV    AX,0100h          { ┬> Synchronous reset              }
  235.               OUT    DX,AX             { ┘                                 }
  236.               MOV    AX,0302h          { ┬> Select Plane 0 & 1 for WRITE   }
  237.               OUT    DX,AX             { ┘                                 }
  238.               MOV    AX,0304h          { ┬> Odd/Even Addressing mode       }
  239.               OUT    DX,AX             { ┘                                 }
  240.               MOV    AX,0300h          { ┬> Release Synchronous reset      }
  241.               OUT    DX,AX             { ┘                                 }
  242.  
  243.               MOV    DX,VGA_GC         { Graphics controller register      }
  244.               MOV    AX,0004h          { ┬> Select Plane 0 for READ        }
  245.               OUT    DX,AX             { ┘                                 }
  246.               MOV    AX,1005h          { ┬> Enable odd addressing mode     }
  247.               OUT    DX,AX             { ┘                                 }
  248.               MOV    AX,0E06h          { ┬> Memory range is B800:0000      }
  249.               OUT    DX,AX             { ┘                                 }
  250.               STI                      { Interrupts enabled                }
  251.  
  252. END;
  253.  
  254.  
  255. PROCEDURE VGA_Set8PixelFont; ASSEMBLER;
  256. ASM
  257.               MOV    DX,003CCh         { Misc output register READ port    }
  258.               IN     AL,DX             { Read value.                       }
  259.               AND    AL,0F3h           { Bits 2 & 3 off (Clock select 0).  }
  260.               MOV    DX,003C2h         { Misc Output Write port            }
  261.               OUT    DX,AL             { Writeback modified value          }
  262.  
  263.               CLI                      { NO interrupts for a while         }
  264.               MOV    DX,03C4h          { Sequencer register                }
  265.               MOV    AX,100h           { \ Generate and hold Synchronous   }
  266.               OUT    DX,AX             { / reset                           }
  267.  
  268.               MOV    AL,001h           { Clocking mode register            }
  269.               OUT    DX,AL             { Activate Clocking mode register   }
  270.               INC    DX                { Data register                     }
  271.               IN     AL,DX             { Read value                        }
  272.               OR     AL,1              { Set Bit 0 (8/9)                   }
  273.               OUT    DX,AL             { Writeback.                        }
  274.               DEC    DX                { Back to Address register          }
  275.  
  276.               MOV    AX,300h           { \ Release Reset state. (normal)   }
  277.               OUT    DX,AX             { /                                 }
  278.  
  279.               MOV    DX,VGA_STATUS     { CRTC Status register              }
  280.               IN     AL,DX             { Read CRTC Status. (This'll reset  }
  281.                                        { Attribute controller flip-flop)   }
  282.               MOV    DX,VGA_AC         { Attribute controller              }
  283.               MOV    AL,13h            { Horizontal Pixel Pan              }
  284.               OUT    DX,AL             { Activate HPP                      }
  285.               MOV    AL,0              { \ Set HPP to 0                    }
  286.               OUT    DX,AL             { /                                 }
  287.               MOV    AL,20h
  288.               OUT    DX,AL             { Set PAS field (Video has access   }
  289.                                        { to palette)                       }
  290.  
  291.               STI                      { Interrupts allowed again          }
  292. END;
  293.  
  294.  
  295. END.
  296.  
  297.  
  298.  
  299.  
  300.  
  301.